/**
 * 融资AI分析服务实现类 - 负责融资申请的智能评估和分析
 *
 * 开发人员：徐少洋
 * 开发时间：2025-11-12 至 2025-11-16
 * 模块职责：实现融资申请的AI智能分析，包括财务健康评估、风险分析、融资建议等功能
 *
 * 技术要点：
 * - AI模型集成和提示词工程
 * - 财务指标分析和风险评估算法
 * - 多租户数据隔离和安全处理
 * - 降级策略和异常处理机制
 * - 融资渠道推荐和成本计算
 *
 * 开发故事：负责融资AI分析服务的核心实现，与融资控制器和前端融资页面深度集成，为企业提供专业的融资决策支持。
 */
package com.pbl.service.impl;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.pbl.common.exception.BizException;
import com.pbl.config.props.AiProps;
import com.pbl.entity.FinancingRequest;
import com.pbl.repository.FinancingRequestRepository;
import com.pbl.service.FinancingAiService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.*;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.math.BigDecimal;
import java.util.*;

@Slf4j
@Service
public class FinancingAiServiceImpl implements FinancingAiService {

    private final AiProps aiProps;
    private final RestTemplate restTemplate;
    private final ObjectMapper objectMapper;
    private final JdbcTemplate jdbcTemplate;
    private final FinancingRequestRepository financingRequestRepository;

    public FinancingAiServiceImpl(AiProps aiProps, 
                                 RestTemplate restTemplate,
                                 ObjectMapper objectMapper,
                                 JdbcTemplate jdbcTemplate,
                                 FinancingRequestRepository financingRequestRepository) {
        this.aiProps = aiProps;
        this.restTemplate = restTemplate;
        this.objectMapper = objectMapper;
        this.jdbcTemplate = jdbcTemplate;
        this.financingRequestRepository = financingRequestRepository;
    }

    @Override
    public Map<String, Object> analyzeFinancingRequest(Long requestId) {
        FinancingRequest request = financingRequestRepository.findById(requestId)
            .orElseThrow(() -> new BizException(404, "融资申请不存在"));
        
        // 获取财务指标
        List<Map<String, Object>> metrics = jdbcTemplate.queryForList(
            "SELECT metric_type, metric_name, metric_value, benchmark_value, industry_average, risk_level " +
            "FROM financial_metrics WHERE enterprise_id = ? AND financing_request_id = ?",
            request.getEnterprise().getId(), requestId
        );
        
        try {
            // 构建AI分析提示
            String prompt = buildFinancingAnalysisPrompt(request, metrics);
            
            // 调用AI分析
            String aiResponse = callAiAnalysis(prompt);
            
            // 解析AI响应
            Map<String, Object> analysis = objectMapper.readValue(aiResponse, new TypeReference<Map<String, Object>>() {});
            analysis.put("requestId", requestId);
            analysis.put("requestedAmount", request.getRequestedAmount());
            analysis.put("purpose", request.getPurpose());
            analysis.put("metrics", metrics);
            return analysis;
        } catch (Exception e) {
            log.error("AI分析失败，使用降级分析", e);
            return createDefaultFinancingAnalysis(request, metrics);
        }
    }

    @Override
    public Map<String, Object> analyzeFinancialHealth(Long enterpriseId) {
        // 获取企业最新财务指标
        List<Map<String, Object>> metrics = jdbcTemplate.queryForList(
            "SELECT metric_type, metric_name, metric_value, benchmark_value, industry_average, risk_level " +
            "FROM financial_metrics WHERE enterprise_id = ? ORDER BY calculation_date DESC LIMIT 20",
            enterpriseId
        );
        
        if (metrics.isEmpty()) {
            return createDefaultHealthAnalysis();
        }
        
        try {
            // 构建AI分析提示
            String prompt = buildHealthAnalysisPrompt(metrics);
            
            // 调用AI分析
            String aiResponse = callAiAnalysis(prompt);
            
            // 解析AI响应
            Map<String, Object> health = objectMapper.readValue(aiResponse, new TypeReference<Map<String, Object>>() {});
            health.put("metrics", metrics);
            return health;
        } catch (Exception e) {
            log.error("AI分析失败，使用降级分析", e);
            return createDefaultHealthAnalysisWithMetrics(metrics);
        }
    }

    @Override
    public Map<String, Object> recommendFinancingChannel(Long enterpriseId, Long requestId) {
        // 获取融资申请信息
        FinancingRequest request = financingRequestRepository.findById(requestId)
            .orElseThrow(() -> new BizException(404, "融资申请不存在"));
        
        // 获取可用渠道
        List<Map<String, Object>> channels = jdbcTemplate.queryForList(
            "SELECT * FROM financing_channels WHERE enterprise_id = ? AND status = 1 ORDER BY interest_rate ASC",
            enterpriseId
        );
        
        // 获取财务健康状况
        Map<String, Object> health = analyzeFinancialHealth(enterpriseId);
        
        // 构建AI推荐提示
        String prompt = buildChannelRecommendationPrompt(request, channels, health);
        
        // 调用AI分析
        String aiResponse = callAiAnalysis(prompt);
        
        // 解析AI响应
        try {
            Map<String, Object> recommendation = objectMapper.readValue(aiResponse, new TypeReference<Map<String, Object>>() {});
            recommendation.put("channels", channels);
            recommendation.put("health", health);
            return recommendation;
        } catch (Exception e) {
            log.error("解析AI响应失败", e);
            throw new BizException(500, "AI分析失败");
        }
    }

    private String buildFinancingAnalysisPrompt(FinancingRequest request, List<Map<String, Object>> metrics) {
        StringBuilder sb = new StringBuilder();
        sb.append("你是一位专业的金融分析师，请基于以下信息分析这笔融资申请：\n\n");
        sb.append("融资申请信息：\n");
        sb.append("- 申请金额：").append(request.getRequestedAmount()).append("元\n");
        sb.append("- 融资用途：").append(request.getPurpose()).append("\n\n");
        
        sb.append("企业财务指标：\n");
        for (Map<String, Object> metric : metrics) {
            sb.append("- ").append(metric.get("metric_name")).append(": ")
              .append(metric.get("metric_value"));
            if (metric.get("benchmark_value") != null) {
                sb.append(" (基准值: ").append(metric.get("benchmark_value")).append(")");
            }
            if (metric.get("industry_average") != null) {
                sb.append(" (行业平均: ").append(metric.get("industry_average")).append(")");
            }
            sb.append(" [风险等级: ").append(metric.get("risk_level")).append("]\n");
        }
        
        sb.append("\n请返回JSON格式的分析结果，包含以下字段：\n");
        sb.append("{\n");
        sb.append("  \"overallScore\": 综合评分(0-100),\n");
        sb.append("  \"riskLevel\": 风险等级(\"LOW\"|\"MEDIUM\"|\"HIGH\"|\"CRITICAL\"),\n");
        sb.append("  \"recommendation\": \"详细的评估建议，包括是否推荐通过以及原因\",\n");
        sb.append("  \"riskScore\": 风险评分(0-100),\n");
        sb.append("  \"creditScore\": 信用评分(0-100),\n");
        sb.append("  \"businessScore\": 业务评分(0-100),\n");
        sb.append("  \"financialScore\": 财务评分(0-100),\n");
        sb.append("  \"riskFactors\": [\"风险因素1\", \"风险因素2\"],\n");
        sb.append("  \"strengths\": [\"优势1\", \"优势2\"],\n");
        sb.append("  \"suggestions\": [\"改进建议1\", \"改进建议2\"]\n");
        sb.append("}\n\n");
        sb.append("请只返回JSON，不要包含其他文字。");
        
        return sb.toString();
    }

    private String buildHealthAnalysisPrompt(List<Map<String, Object>> metrics) {
        StringBuilder sb = new StringBuilder();
        sb.append("你是一位专业的财务分析师，请基于以下财务指标分析企业的财务健康状况：\n\n");
        
        sb.append("企业财务指标：\n");
        for (Map<String, Object> metric : metrics) {
            sb.append("- ").append(metric.get("metric_name")).append(": ")
              .append(metric.get("metric_value"));
            if (metric.get("benchmark_value") != null) {
                sb.append(" (基准值: ").append(metric.get("benchmark_value")).append(")");
            }
            if (metric.get("industry_average") != null) {
                sb.append(" (行业平均: ").append(metric.get("industry_average")).append(")");
            }
            sb.append(" [风险等级: ").append(metric.get("risk_level")).append("]\n");
        }
        
        sb.append("\n请返回JSON格式的分析结果，包含以下字段：\n");
        sb.append("{\n");
        sb.append("  \"overallHealth\": 总体健康状况(\"EXCELLENT\"|\"GOOD\"|\"FAIR\"|\"POOR\"),\n");
        sb.append("  \"healthScore\": 健康评分(0-100),\n");
        sb.append("  \"riskFactors\": [\"风险因素描述\"],\n");
        sb.append("  \"improvementSuggestions\": [\"改进建议\"],\n");
        sb.append("  \"timing\": \"融资时机建议的详细说明\",\n");
        sb.append("  \"liquidityAnalysis\": \"流动性分析\",\n");
        sb.append("  \"profitabilityAnalysis\": \"盈利能力分析\",\n");
        sb.append("  \"leverageAnalysis\": \"杠杆分析\",\n");
        sb.append("  \"growthAnalysis\": \"成长性分析\"\n");
        sb.append("}\n\n");
        sb.append("请只返回JSON，不要包含其他文字。");
        
        return sb.toString();
    }

    private String buildChannelRecommendationPrompt(FinancingRequest request, 
                                                   List<Map<String, Object>> channels, 
                                                   Map<String, Object> health) {
        StringBuilder sb = new StringBuilder();
        sb.append("你是一位专业的融资顾问，请基于以下信息推荐最合适的融资渠道：\n\n");
        
        sb.append("融资需求：\n");
        sb.append("- 申请金额：").append(request.getRequestedAmount()).append("元\n");
        sb.append("- 融资用途：").append(request.getPurpose()).append("\n\n");
        
        sb.append("企业财务健康状况：").append(health.get("overallHealth")).append("\n");
        if (health.get("healthScore") != null) {
            sb.append("健康评分：").append(health.get("healthScore")).append("\n");
        }
        sb.append("\n");
        
        sb.append("可用融资渠道：\n");
        for (int i = 0; i < channels.size(); i++) {
            Map<String, Object> channel = channels.get(i);
            sb.append((i + 1)).append(". ").append(channel.get("channel_name")).append("\n");
            sb.append("   - 类型：").append(channel.get("channel_type")).append("\n");
            sb.append("   - 利率：").append(new BigDecimal(channel.get("interest_rate").toString())
                .multiply(new BigDecimal("100"))).append("%\n");
            sb.append("   - 额度范围：").append(channel.get("min_amount")).append(" - ")
              .append(channel.get("max_amount")).append("元\n");
            sb.append("   - 期限：").append(channel.get("term_months")).append("个月\n");
            sb.append("   - 优势：").append(channel.get("advantages")).append("\n");
            sb.append("   - 劣势：").append(channel.get("disadvantages")).append("\n\n");
        }
        
        sb.append("请返回JSON格式的推荐结果，包含以下字段：\n");
        sb.append("{\n");
        sb.append("  \"bestChannelId\": 最推荐的渠道ID,\n");
        sb.append("  \"bestChannelName\": \"最推荐的渠道名称\",\n");
        sb.append("  \"recommendationReason\": \"推荐理由的详细说明\",\n");
        sb.append("  \"alternativeChannels\": [\n");
        sb.append("    {\"channelId\": 备选渠道ID, \"reason\": \"备选理由\"}\n");
        sb.append("  ],\n");
        sb.append("  \"costAnalysis\": \"成本分析说明\",\n");
        sb.append("  \"riskAnalysis\": \"风险分析说明\",\n");
        sb.append("  \"timing\": \"融资时机建议\",\n");
        sb.append("  \"nextSteps\": [\"下一步行动建议\"]\n");
        sb.append("}\n\n");
        sb.append("请只返回JSON，不要包含其他文字。");
        
        return sb.toString();
    }

    private String callAiAnalysis(String prompt) {
        int maxRetries = 3;
        int retryDelay = 2000; // 2秒
        
        for (int attempt = 1; attempt <= maxRetries; attempt++) {
            try {
                HttpHeaders headers = new HttpHeaders();
                headers.setContentType(MediaType.APPLICATION_JSON);
                headers.setBearerAuth(aiProps.getApiKey());
                
                Map<String, Object> requestBody = new HashMap<>();
                requestBody.put("model", aiProps.getAnalysisModel());
                requestBody.put("messages", List.of(
                    Map.of("role", "user", "content", prompt)
                ));
                requestBody.put("temperature", 0.3); // 低温度以获得更稳定的结果
                requestBody.put("max_tokens", 2000);
                
                HttpEntity<Map<String, Object>> entity = new HttpEntity<>(requestBody, headers);
                
                log.info("调用AI分析，模型: {} (第{}次尝试)", aiProps.getAnalysisModel(), attempt);
                
                ResponseEntity<Map> response = restTemplate.postForEntity(
                    aiProps.getBaseUrl() + "/chat/completions",
                    entity,
                    Map.class
                );
                
                if (response.getStatusCode() == HttpStatus.OK && response.getBody() != null) {
                    Map<String, Object> body = response.getBody();
                    List<Map<String, Object>> choices = (List<Map<String, Object>>) body.get("choices");
                    if (choices != null && !choices.isEmpty()) {
                        Map<String, Object> message = (Map<String, Object>) choices.get(0).get("message");
                        String content = (String) message.get("content");
                        
                        // 提取JSON内容（去除可能的markdown格式）
                        content = content.trim();
                        if (content.startsWith("```json")) {
                            content = content.substring(7);
                        } else if (content.startsWith("```")) {
                            content = content.substring(3);
                        }
                        if (content.endsWith("```")) {
                            content = content.substring(0, content.length() - 3);
                        }
                        content = content.trim();
                        
                        log.info("AI分析结果: {}", content);
                        return content;
                    }
                }
                
                throw new BizException(500, "AI服务调用失败");
                
            } catch (org.springframework.web.client.HttpServerErrorException e) {
                if (e.getStatusCode() == HttpStatus.SERVICE_UNAVAILABLE && attempt < maxRetries) {
                    log.warn("AI服务繁忙，{}秒后重试 (第{}次尝试)", retryDelay / 1000, attempt);
                    try {
                        Thread.sleep(retryDelay);
                        retryDelay *= 2; // 指数退避
                    } catch (InterruptedException ie) {
                        Thread.currentThread().interrupt();
                        throw new BizException(500, "AI服务调用被中断");
                    }
                    continue;
                }
                log.error("调用AI服务失败 (第{}次尝试)", attempt, e);
                throw new BizException(500, "AI服务调用失败: " + e.getMessage());
            } catch (Exception e) {
                log.error("调用AI服务失败 (第{}次尝试)", attempt, e);
                if (attempt == maxRetries) {
                    throw new BizException(500, "AI服务调用失败: " + e.getMessage());
                }
                try {
                    Thread.sleep(retryDelay);
                } catch (InterruptedException ie) {
                    Thread.currentThread().interrupt();
                    throw new BizException(500, "AI服务调用被中断");
                }
            }
        }
        
        throw new BizException(500, "AI服务调用失败，已重试" + maxRetries + "次");
    }

    private Map<String, Object> createDefaultHealthAnalysis() {
        Map<String, Object> health = new HashMap<>();
        health.put("overallHealth", "FAIR");
        health.put("healthScore", 50);
        health.put("riskFactors", List.of("缺少财务数据，无法进行准确评估"));
        health.put("improvementSuggestions", List.of("建议补充完整的财务报表数据"));
        health.put("timing", "由于缺少足够的财务数据，建议先完善财务信息后再考虑融资");
        health.put("metrics", new ArrayList<>());
        return health;
    }

    private Map<String, Object> createDefaultHealthAnalysisWithMetrics(List<Map<String, Object>> metrics) {
        Map<String, Object> health = new HashMap<>();
        
        // 基于财务指标计算健康评分
        int lowRiskCount = 0;
        int highRiskCount = 0;
        for (Map<String, Object> metric : metrics) {
            String riskLevel = (String) metric.get("risk_level");
            if ("LOW".equals(riskLevel)) {
                lowRiskCount++;
            } else if ("HIGH".equals(riskLevel) || "CRITICAL".equals(riskLevel)) {
                highRiskCount++;
            }
        }
        
        String overallHealth;
        int healthScore;
        if (lowRiskCount >= metrics.size() * 0.7) {
            overallHealth = "EXCELLENT";
            healthScore = 85;
        } else if (lowRiskCount >= metrics.size() * 0.5) {
            overallHealth = "GOOD";
            healthScore = 75;
        } else if (highRiskCount <= metrics.size() * 0.3) {
            overallHealth = "FAIR";
            healthScore = 60;
        } else {
            overallHealth = "POOR";
            healthScore = 40;
        }
        
        health.put("overallHealth", overallHealth);
        health.put("healthScore", healthScore);
        health.put("riskFactors", List.of("基于财务指标的基础分析"));
        health.put("improvementSuggestions", List.of("建议优化财务指标，降低风险等级"));
        health.put("timing", "建议在财务指标改善后再考虑融资");
        health.put("metrics", metrics);
        return health;
    }

    private Map<String, Object> createDefaultFinancingAnalysis(FinancingRequest request, List<Map<String, Object>> metrics) {
        Map<String, Object> analysis = new HashMap<>();
        analysis.put("requestId", request.getId());
        analysis.put("requestedAmount", request.getRequestedAmount());
        analysis.put("purpose", request.getPurpose());
        analysis.put("metrics", metrics);
        
        // 基于财务指标计算评分
        int lowRiskCount = 0;
        int highRiskCount = 0;
        for (Map<String, Object> metric : metrics) {
            String riskLevel = (String) metric.get("risk_level");
            if ("LOW".equals(riskLevel)) {
                lowRiskCount++;
            } else if ("HIGH".equals(riskLevel) || "CRITICAL".equals(riskLevel)) {
                highRiskCount++;
            }
        }
        
        int overallScore;
        String riskLevel;
        String recommendation;
        
        if (lowRiskCount >= metrics.size() * 0.7) {
            overallScore = 85;
            riskLevel = "LOW";
            recommendation = "财务状况良好，建议通过融资申请";
        } else if (lowRiskCount >= metrics.size() * 0.5) {
            overallScore = 70;
            riskLevel = "MEDIUM";
            recommendation = "财务状况一般，建议谨慎考虑";
        } else if (highRiskCount <= metrics.size() * 0.3) {
            overallScore = 55;
            riskLevel = "HIGH";
            recommendation = "财务状况较差，建议暂缓融资";
        } else {
            overallScore = 35;
            riskLevel = "CRITICAL";
            recommendation = "财务状况很差，不建议通过";
        }
        
        analysis.put("overallScore", overallScore);
        analysis.put("riskLevel", riskLevel);
        analysis.put("recommendation", recommendation);
        analysis.put("riskScore", 100 - overallScore);
        analysis.put("creditScore", overallScore);
        analysis.put("businessScore", overallScore);
        analysis.put("financialScore", overallScore);
        analysis.put("riskFactors", List.of("基于财务指标的基础风险评估"));
        analysis.put("strengths", List.of("需要进一步分析"));
        analysis.put("suggestions", List.of("建议完善财务数据以获得更准确的分析"));
        
        return analysis;
    }
}

